package site.edody.dframe.websocket;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * DFrame WebSocket 数据缓存
 * @author Dody
 */
public class DFrameWebSocketDataCache {
    private static final Logger log = LoggerFactory.getLogger(DFrameWebSocketDataCache.class);

    // 存储结构: Map<serverName, Map<dataKey, Object>>
    private final ConcurrentHashMap<String, ConcurrentHashMap<String, Object>> dataCache =
            new ConcurrentHashMap<>();

    // 存储音频数据的结构: Map<serverName, Map<sessionKey, Map<sequence, data>>>
    private final ConcurrentHashMap<String, ConcurrentHashMap<String, ConcurrentHashMap<Integer, String>>> audioDataCache =
            new ConcurrentHashMap<>();

    public void put(String serverName, String dataKey, Object data) {
        dataCache.computeIfAbsent(serverName, k -> new ConcurrentHashMap<>())
                .put(dataKey, data);
        log.debug("[DFrame-{}] Put data with key: {}", serverName, dataKey);
    }

    public Object get(String serverName, String dataKey) {
        ConcurrentHashMap<String, Object> serverData = dataCache.get(serverName);
        Object result = serverData != null ? serverData.get(dataKey) : null;
        log.debug("[DFrame-{}] Get data with key: {}, found: {}", serverName, dataKey, result != null);
        return result;
    }

    public void remove(String serverName, String dataKey) {
        ConcurrentHashMap<String, Object> serverData = dataCache.get(serverName);
        if (serverData != null) {
            serverData.remove(dataKey);
            log.debug("[DFrame-{}] Removed data with key: {}", serverName, dataKey);
        }
    }

    public void clearServerData(String serverName) {
        dataCache.remove(serverName);
        audioDataCache.remove(serverName);
        log.info("[DFrame-{}] Cleared all data", serverName);
    }

    public Map<String, Object> getServerData(String serverName) {
        ConcurrentHashMap<String, Object> serverData = dataCache.get(serverName);
        return serverData != null ? new ConcurrentHashMap<>(serverData) : new ConcurrentHashMap<>();
    }

    // 音频数据相关方法
    public void putAudioData(String serverName, String sessionKey, Integer sequence, String audioData) {
        audioDataCache.computeIfAbsent(serverName, k -> new ConcurrentHashMap<>())
                .computeIfAbsent(sessionKey, k -> new ConcurrentHashMap<>())
                .put(sequence, audioData);
        log.debug("[DFrame-{}] Put audio data for session: {}, sequence: {}", serverName, sessionKey, sequence);
    }

    public String getAudioData(String serverName, String sessionKey, Integer sequence) {
        ConcurrentHashMap<String, ConcurrentHashMap<Integer, String>> serverAudioData = audioDataCache.get(serverName);
        if (serverAudioData != null) {
            ConcurrentHashMap<Integer, String> sessionData = serverAudioData.get(sessionKey);
            if (sessionData != null) {
                return sessionData.get(sequence);
            }
        }
        return null;
    }

    public Map<Integer, String> getSessionAudioData(String serverName, String sessionKey) {
        ConcurrentHashMap<String, ConcurrentHashMap<Integer, String>> serverAudioData = audioDataCache.get(serverName);
        if (serverAudioData != null) {
            ConcurrentHashMap<Integer, String> sessionData = serverAudioData.get(sessionKey);
            return sessionData != null ? new ConcurrentHashMap<>(sessionData) : new ConcurrentHashMap<>();
        }
        return new ConcurrentHashMap<>();
    }

    public void removeAudioData(String serverName, String sessionKey, Integer sequence) {
        ConcurrentHashMap<String, ConcurrentHashMap<Integer, String>> serverAudioData = audioDataCache.get(serverName);
        if (serverAudioData != null) {
            ConcurrentHashMap<Integer, String> sessionData = serverAudioData.get(sessionKey);
            if (sessionData != null) {
                sessionData.remove(sequence);
                log.debug("[DFrame-{}] Removed audio data for session: {}, sequence: {}", serverName, sessionKey, sequence);
            }
        }
    }

    public void clearSessionAudioData(String serverName, String sessionKey) {
        ConcurrentHashMap<String, ConcurrentHashMap<Integer, String>> serverAudioData = audioDataCache.get(serverName);
        if (serverAudioData != null) {
            serverAudioData.remove(sessionKey);
            log.info("[DFrame-{}] Cleared all audio data for session: {}", serverName, sessionKey);
        }
    }

    public int getAudioDataCount(String serverName, String sessionKey) {
        ConcurrentHashMap<String, ConcurrentHashMap<Integer, String>> serverAudioData = audioDataCache.get(serverName);
        if (serverAudioData != null) {
            ConcurrentHashMap<Integer, String> sessionData = serverAudioData.get(sessionKey);
            return sessionData != null ? sessionData.size() : 0;
        }
        return 0;
    }
}